import java.util.Scanner;

public class Day_four {


    //杨辉三角（动态规划）
    //描述
    //KiKi知道什么叫杨辉三角之后对杨辉三角产生了浓厚的兴趣，他想知道杨辉三角的前n行，请编程帮他解答。杨辉三角，本质上是二项式(a+b)的n次方展开后各项的系数排成的三角形。其性质包括：每行的端点数为1， 一个数也为1；每个数等于它左上方和上方的两数之和。
    //输入描述：
    //第一行包含一个整数数n。 (1≤n≤30)
    //输出描述：
    //包含n行，为杨辉三角的前n行，每个数输出域宽为5。
    //示例1
    //输入：
    //6
    //输出：
    //    1
    //    1    1
    //    1    2    1
    //    1    3    3    1
    //    1    4    6    4    1
    //    1    5   10   10    5    1
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);

        int n = s.nextInt();

        int[][] dp = new int[n+1][n+1];
        dp[1][1] = 1;

        for (int i = 2; i <= n; i++) {
            for (int j = 1; j <= i; j++) {
                dp[i][j] = dp[i-1][j-1] +dp[i-1][j];
            }
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= i; j++) {
                StringBuffer ret = new StringBuffer();
                int len = Integer.toString(dp[i][j]).length();
                for (int k = 0; k < 5-len; k++) {
                    ret.append(" ");
                }
                System.out.print(dp[i][j]+ret.toString());
            }
            System.out.println();
        }
    }


    //单词搜索
    //描述
    //给出一个二维字符数组和一个单词，判断单词是否在数组中出现，
    //单词由相邻单元格的字母连接而成，相邻单元指的是上下左右相邻。同一单元格的字母不能多次使用。
    //数据范围：
    //0 < 行长度 <= 100
    //0 < 列长度 <= 100
    //0 < 单词长度 <= 1000
    //例如：
    //给出的数组为["XYZE","SFZS","XDEE"]时，
    //对应的二维字符数组为：
    // X Y Z E
    // S F Z S
    // X D E E
    //若单词为"XYZZED"时，应该返回 true，
    //也即：
    // x y z E
    // S F z S
    // X d e E
    //若单词为"SEE"时，应该返回 true，
    //也即：
    // X Y Z E
    // S F Z s
    // X D e e
    //若单词为"XYZY"时，应该返回 false。
    //示例1
    //输入：
    //["XYZE","SFZS","XDEE"],"XYZZED"
    //返回值：
    //true
    public  class  Solution{
        int m,n;
        int[] dx= {0,0,1,-1};
        int[] dy= {1,-1,0,0};
        boolean[][] vis;
        char[] word;

        public boolean exist(String[] board,String _word){
            m = board.length;
            n = board[0].length();
            vis = new boolean[m][n];
            word = _word.toCharArray();

            for (int i = 0; i < m; i++) {
                for (int j = 0; j <n; j++) {
                    if (board[i].charAt(j) == word[0]){
                        if (dfs(board,i,j,0) == true) return true;
                    }
                }
            }
            return false;
        }

        public boolean dfs(String[] board,int i,int j,int pos){
            if (pos == word.length-1){
                return true;
            }

            vis[i][j] = true;
            for (int k = 0; k < 4; k++) {
                int x = i + dx[k], y = j + dy[k];

                if (x>=0 && x<m && y>=0 && y<n && !vis[x][y] && board[x].charAt(y) == word[pos+1]){
                    if (dfs(board,x,y,pos+1)) return true;
                }
            }
            vis[i][j] = true;

            return false;
        }
    }


    //Fibonacci数列
    //描述
    //Fibonacci数列是这样定义的：
    //F[0] = 0
    //F[1] = 1
    //for each i ≥ 2: F[i] = F[i-1] + F[i-2]
    //因此，Fibonacci数列就形如：0, 1, 1, 2, 3, 5, 8, 13, 21...，在Fibonacci数列中的数我们称为Fibonacci数。
    //给你一个N，你想让其变为一个Fibonacci数，每一步你可以把当前数字X变为X-1或者X+1，现在给你一个数N求最少需要多少步可以变为Fibonacci数。
    //输入描述：
    //输入为一个正整数N(1 ≤ N ≤ 1,000,000)
    //输出描述：
    //输出一个最小的步数变为Fibonacci数"
    //示例1
    //输入：
    //15
    //输出：
    //2
    public static void main1(String[] args) {
        Scanner s = new Scanner(System.in);

        int n = s.nextInt();

        int a = 0, b = 1, c = 1;

        while(n>c){
            a=b;
            b=c;
            c=a+b;
        }
        System.out.println(Math.min(n-b,c-n));
    }
}
